package com.demo.springboot底层演示.demo1;

import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;

@Configuration
public class Test {

	public static void main(String[] args) throws Exception {
		System.out.println("1. 演示获取bean Definition源");
		SpringApplication spring = new SpringApplication(Test.class);
		// 可以加入xml配置文件
		// spring.setSources(sources);
		System.out.println("2. 演示推断应用类型：普通还是web");
		System.out.println("3. 演示ApplicationContext初始化器");
		spring.addInitializers(applicationContext -> {
			if(applicationContext instanceof GenericApplicationContext) {
				GenericApplicationContext gac = (GenericApplicationContext)applicationContext;
				gac.registerBeanDefinition("bean3", new AnnotatedGenericBeanDefinition(Bean3.class));
			}
		});
		System.out.println("4. 演示监听器与事件");
		spring.addListeners(event -> System.out.println("\t事件为：" + event.getClass()));
		System.out.println("5. 演示主类推断");
		Method deduceMainApplicationClass = SpringApplication.class.getDeclaredMethod("deduceMainApplicationClass");
		deduceMainApplicationClass.setAccessible(true);
		System.out.println("主类是：" + deduceMainApplicationClass.invoke(spring));
		ConfigurableApplicationContext context = spring.run(args);
		for(String name : context.getBeanDefinitionNames()) {
			System.out.println("name: " + name + " 来源：" + context.getBeanFactory().getBeanDefinition(name).getResourceDescription());
		}
	}
	
	// 内嵌web容器工厂
	@Bean
	public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
		return new TomcatEmbeddedServletContainerFactory();
	}
	
	@Bean
	public Bean2 bean2() {
		return new Bean2();
	}
	
}
